package com.wlsk.license.common.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ListenableFuture;
import com.wlsk.license.common.bo.AdminUserBo;
import com.wlsk.license.common.constant.RedisService;
import com.wlsk.license.common.exception.BusinessException;
import com.wlsk.license.common.result.Result;
import com.wlsk.license.dto.request.feign.UserIdReqDto;
import com.wlsk.license.dto.response.feign.CenterManagerInfoResultDto;
import com.wlsk.license.service.feign.CenterManagerClient;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @description: 管理端用户会话管理
 * @author: liuzhangbin
 * @date: 2025/2/20
 */
@Slf4j
public final class AdminSessionManager {

    private static final String ADMIN_USER_PREFIX = "chartered:user:admin:%s";

    private static final LoadingCache<Long, AdminUserBo> cache = CacheBuilder.newBuilder().expireAfterAccess(20, TimeUnit.MINUTES).refreshAfterWrite(5, TimeUnit.MINUTES).build(new CacheLoader<Long, AdminUserBo>() {
        @Override
        public AdminUserBo load(Long uid) throws Exception {
            log.info("获取用户信息uid:{}", uid);
            return AdminSessionManager.get(uid);
        }

        @Override
        public ListenableFuture<AdminUserBo> reload(Long uid, AdminUserBo oldValue) throws Exception {
            return super.reload(uid, oldValue);
        }
    });

    /**
     * 获取管理用户信息
     *
     * @param uid
     * @return
     */
    private static AdminUserBo get(Long uid) {
        ValidationUtils.notNull(uid, "用户ID不能为空");
        String key = String.format(ADMIN_USER_PREFIX, uid.toString());
        RedisService redisService = SpringUtil.getBean(RedisService.class);
        AdminUserBo adminUserBo = redisService.getCacheObject(key);
        if (Objects.isNull(adminUserBo)) {
            CenterManagerClient centerManagerClient = SpringUtil.getBean(CenterManagerClient.class);
            Result<CenterManagerInfoResultDto> result = centerManagerClient.getUserInfoById(new UserIdReqDto(uid));
            ValidationUtils.isTrue(result.isSuccess(), "获取用户信息错误");
            adminUserBo = BeanUtil.copyProperties(result.getData(), AdminUserBo.class);
            redisService.setCacheObject(key, adminUserBo, 20L, TimeUnit.MINUTES);
        }
        return adminUserBo;
    }

    /**
     * 获取管理用户信息
     *
     * @param uid
     * @return
     */
    public static AdminUserBo getAdminUser(Long uid) {
        try {
            AdminUserBo adminUserBo = cache.get(uid);
            ValidationUtils.notNull(adminUserBo, "获取用户信息错误");
            return adminUserBo;
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取管理用户{}异常，详情:{}", uid, e.getMessage(), e);
            throw new BusinessException("获取用户信息错误");
        }
    }

    /**
     * 获取管理用户姓名
     *
     * @param uid
     * @return
     */
    public static String getName(Long uid) {
        return getAdminUser(uid).getNickname();
    }

}
